package com.gosophia.metadataEngine.service.impl;

import java.util.ArrayList;
import java.util.List;

import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;
import org.springframework.util.Assert;

import com.gosophia.commons.OrderCondition;
import com.gosophia.commons.Page;
import com.gosophia.commons.PropertyFilter;
import com.gosophia.commons.exception.BusinessException;
import com.gosophia.commons.exception.ConcurrencyException;
import com.gosophia.commons.exception.ExceptionDetail;
import com.gosophia.metadataEngine.commons.DBUtil;
import com.gosophia.metadataEngine.dao.DataSourceInfoDao;
import com.gosophia.metadataEngine.dao.MetaDataFiledDao;
import com.gosophia.metadataEngine.dao.MetaDataTableDao;
import com.gosophia.metadataEngine.entity.MetaDataField;
import com.gosophia.metadataEngine.entity.MetaDataTable;
import com.gosophia.metadataEngine.service.MetaDataTableService;
/**
 * 元数据表impl
 * @author mayue
 *
 */
@Service("metaDataTableService")
@Transactional
public class MetaDataTableServiceImpl implements MetaDataTableService{
    @Autowired
    private MetaDataTableDao metaDataTableDao;
    @Autowired
    private DataSourceInfoDao dtaSourceInfoDao;
    /****
     * 添加元数据表信息:
     * metaDataTable,tableName,tableNameCN,entityClassName不能为null，metaDataTableId必须为null,
     * dataSourceInfo不能为null
     * @param metaDataTable 元数据表实体
     */
    public void addMetaDataTable(MetaDataTable metaDataTable)
            throws BusinessException {
        Assert.notNull(metaDataTable,"metaDataTable不能为null");
        Assert.notNull(metaDataTable.getTableName(),"tableName不能为null");
        Assert.notNull(metaDataTable.getTableNameCN(),"tableNameCN不能为null");
        Assert.notNull(metaDataTable.getEntityClassName(),"entityClassName不能为null");
        Assert.isNull(metaDataTable.getMetaDataTableId(),"MetaDataTableId必须为null");
        Assert.notNull(metaDataTable.getDataSourceInfo(),"dataSourceInfo不能为null");
        Long count = metaDataTableDao.
                    countNamedQueryResult("MetaDataTable.findBySameName", metaDataTable.getTableName(),metaDataTable.getTableNameCN(),metaDataTable.getEntityClassName());
        if(count>0){
            throw new BusinessException("表名/表中文名/实体类名有重复！","JC2_YSJ_B_9");
        }
        List<MetaDataField> dataFields = DBUtil.readTableStructure(dtaSourceInfoDao.get(metaDataTable.getDataSourceInfo().getDataSourceInfoId()), metaDataTable.getTableName());
        for(MetaDataField field : dataFields){
        	field.setMetaDataTable(metaDataTable);
        }
        metaDataTable.setMetaDataFields(dataFields);
        metaDataTableDao.save(metaDataTable);
    }

    public Page<MetaDataTable> findAllMetaDataTableByPage(int pageSize, int pageNo) {
        Assert.isTrue(pageSize > 0, "pageSize必须大于0");
        Assert.isTrue(pageNo > 0, "pageNo必须大于0");
        Page<MetaDataTable> page = new Page<MetaDataTable>();
        page.setPageSize(pageSize);
        page.setPageNo(pageNo);
        return  metaDataTableDao.getPage(page);
    }

    public MetaDataTable findMetaDataTableById(Long metaDataTableId) {
        Assert.notNull(metaDataTableId,"metaDataTableId不能为null");
        return metaDataTableDao.get(metaDataTableId);
    }
    /**
     * 删除元数据表信息:
     * metaDataTableId,version 不能为null
     * @param metaDataTableId
     * @param version
     * @throws BusinessException：当表有引用时
     */
    public MetaDataTable removeMetaDataTable(Long metaDataTableId, Long version)
            throws BusinessException {
        Assert.notNull(metaDataTableId,"metaDataTableId不能为null");
        Assert.notNull(version,"version不能为null");
        MetaDataTable mdt = metaDataTableDao.get(metaDataTableId);
        if(mdt == null){
           throw new ConcurrencyException("该元数据表记录已被删除！",new ExceptionDetail("JC2_YSJ_C_9","该元数据表记录已被删除！"));
        }
        if(!version.equals(mdt.getVersion())){
            throw new ConcurrencyException("该元数据表记录已被修改！",new ExceptionDetail("JC2_YSJ_C_10","该元数据表记录已被修改！"));
        }
        try {
            metaDataTableDao.delete(metaDataTableId, version);
            return mdt;
        } catch (Exception e) {
            throw new BusinessException("该元数据表记录被引用，不能删除！", "JC2_YSJ_B_10");
        }
        
        
    }
    /**
     * 修改元数据表信息:
     * metaDataTable,tableName,tableNameCN,entityClassName不能为null
     * @param metaDataTable
     */
    public void updateMetaDataTable(MetaDataTable metaDataTable)
            throws BusinessException {
        Assert.notNull(metaDataTable,"metaDataTable不能为null");
        Assert.notNull(metaDataTable.getTableName(),"tableName不能为null");
        Assert.notNull(metaDataTable.getTableNameCN(),"tableNameCN 不能为null");
        Assert.notNull(metaDataTable.getEntityClassName(),"entityClassName不能为null");
        Assert.notNull(metaDataTable.getDataSourceInfo(),"dataSourceInfo不能为null");
        MetaDataTable mdt = metaDataTableDao.get(metaDataTable.getMetaDataTableId());
        if(mdt == null){
            throw new ConcurrencyException("该数据表记录已被删除！",new ExceptionDetail("JC2_YSJ_C_11","该数据表记录已被删除！"));
         }
        if(!metaDataTable.getVersion().equals(mdt.getVersion())){
             throw new ConcurrencyException("该数据表记录已被修改！",new ExceptionDetail("JC2_YSJ_C_12","该数据表记录已被修改！"));
         }
        Long count = metaDataTableDao.countNamedQueryResult("MetaDataTable.findBySameParamButId",
                metaDataTable.getTableName(),metaDataTable.getTableNameCN(),metaDataTable.getEntityClassName(),metaDataTable.getMetaDataTableId());
        if(count>0){
            throw new BusinessException("表名/表中文名/实体类名有重复！","JC2_YSJ_B_11");
        }
        metaDataTable.setCreateTime(mdt.getCreateTime());
        metaDataTableDao.update(metaDataTable);
        
    }
    
    //根据DataSourceInfo下的所有MetaDataTable
    //wangxinbing 2011-4-28
    @Override
    public List<MetaDataTable> findMetaDataTablesByDataSourceInfoId(Long dataSourceInfoId){
    	Assert.notNull(dataSourceInfoId,"dataSourceInfoId不能为null");
    	List<MetaDataTable> metaDataTables = metaDataTableDao.getListByNamedQuery("metaDataTableService.findMetaDataTablesByDataSourceInfoId", dataSourceInfoId);
    	return metaDataTables;
    }

	@Override
	public Page<MetaDataTable> findMetadataTablePageByDataSourceInfoId(
			Long dataSourceInfoId, Page<MetaDataTable> page,
			String searchString, List<OrderCondition> orderConditions) {
		Assert.notNull(dataSourceInfoId,"dataSourceInfoId不能为null");
		Assert.notNull(page,"page不能为null");
        Assert.isTrue(page.getPageSize()>0, "pageSize必须大于0");
        Assert.isTrue(page.getPageNo()>0,"pageNo必须大于0");
        List<PropertyFilter> propertyFilters = new ArrayList<PropertyFilter>();
        PropertyFilter p = new PropertyFilter();
        p.setPropertyName("dataSourceInfo.dataSourceInfoId");
        p.setPropertyValue(dataSourceInfoId);
        propertyFilters.add(p);
		return metaDataTableDao.getPageBySimpleSearching(page, searchString, null, propertyFilters , orderConditions);
	}


}
